package com.example.demo.service.impl;

import com.alibaba.fastjson.JSON;
import com.example.demo.controller.exception.BizException;
import com.example.demo.controller.req.OperationStatInsertReq;
import com.example.demo.controller.resp.OperationCountResp;
import com.example.demo.controller.resp.OperationListResp;
import com.example.demo.data.dao.OperationDao;
import com.example.demo.data.dao.UserDao;
import com.example.demo.data.entity.OperationDO;
import com.example.demo.data.entity.UserDO;
import com.example.demo.service.OperationService;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class OperationServiceImpl implements OperationService {

    @Resource
    private OperationDao operationDao;

    @Resource
    private UserDao userDao;

    @Override
    public void insert(OperationStatInsertReq req) {
        checkUser(req.getActiveCode());

        // insert
        OperationDO operation = new OperationDO();
        operation.setActionType(1);
        operation.setCreateTime(new Timestamp(System.currentTimeMillis()));
        operation.setEntityCount(req.getNumber());
        operation.setEntityName(req.getType());
        operation.setUserIdentify(req.getActiveCode());
        operation.setExtra(JSON.toJSONString(req));

        operationDao.save(operation);
    }

    @Override
    public List<OperationListResp> showAll(String identify) {
        checkUser(identify);

        // find
        List<OperationDO> operations = operationDao.findAllByUserIdentify(identify);
        if (CollectionUtils.isEmpty(operations)) {
            return new ArrayList<>();
        }

        // equip
        List<OperationListResp> list = new ArrayList<>();
        for (OperationDO operation : operations) {
            OperationListResp item = new OperationListResp();
            item.setNumber(operation.getEntityCount());
            item.setType(operation.getEntityName());
            item.setTimestamp(operation.getCreateTime().getTime());

            list.add(item);
        }

        return list;
    }

    @Override
    public List<OperationCountResp> count(String identify) {
        checkUser(identify);
        // find
        List<OperationDO> operations = operationDao.findAllByUserIdentify(identify);
        if (CollectionUtils.isEmpty(operations)) {
            return new ArrayList<>();
        }

        Map<String, List<OperationDO>> map = operations.stream().collect(Collectors.groupingBy(OperationDO::getEntityName));
        // equip
        List<OperationCountResp> list = new ArrayList<>();
        for (Map.Entry<String, List<OperationDO>> entry : map.entrySet()) {
            OperationCountResp item = new OperationCountResp();
            item.setType(entry.getKey());
            item.setNumber(entry.getValue().stream().mapToInt(OperationDO::getEntityCount).sum());
            list.add(item);
        }

        return list;
    }

    private void checkUser(String code) throws BizException {
        UserDO user = userDao.findByIdentity(code);
        if (user == null) {
            throw new BizException("激活码不存在");
        }
    }
}
